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
6607295e
Commit
6607295e
authored
Nov 10, 2025
by
Luna Riegel
Browse files
Refactor: Use DB for error filtering in NodeTrees
parent
76cdabcb
Changes
8
Hide whitespace changes
Inline
Side-by-side
.run/CityDoctorGUIStarter.run.xml
View file @
6607295e
...
...
@@ -2,6 +2,7 @@
<configuration
default=
"false"
name=
"CityDoctorGUIStarter"
type=
"Application"
factoryName=
"Application"
nameIsGenerated=
"true"
>
<option
name=
"MAIN_CLASS_NAME"
value=
"de.hft.stuttgart.citydoctor2.gui.CityDoctorGUIStarter"
/>
<module
name=
"CityDoctorGUI"
/>
<option
name=
"WORKING_DIRECTORY"
value=
"$MODULE_WORKING_DIR$"
/>
<extension
name=
"coverage"
>
<pattern>
<option
name=
"PATTERN"
value=
"de.hft.stuttgart.citydoctor2.gui.*"
/>
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/database/CacheManager.java
View file @
6607295e
...
...
@@ -25,6 +25,12 @@ public class CacheManager {
}
}
public
static
void
synchronizeCache
(){
if
(
cache
!=
null
){
cache
.
synchronize
();
}
}
public
static
UnconnectedCache
getUnconnectedCache
(){
return
new
UnconnectedCache
();
}
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/database/DatabaseHandler.java
View file @
6607295e
...
...
@@ -36,10 +36,12 @@ public class DatabaseHandler {
public
DatabaseHandler
(){
try
{
String
jdbcurl
=
H2GISDBFactory
.
createDataSource
(
DB_NAME
,
true
,
";AUTO_SERVER=TRUE"
).
getConnection
().
getMetaData
().
getURL
();
// String jdbcurl = H2GISDBFactory.createDataSource(DB_NAME,
// true, ";AUTO_SERVER=TRUE").getConnection().getMetaData().getURL();
String
jdbcurl
=
H2GISDBFactory
.
createSpatialDataBase
(
DB_NAME
,
true
,
";AUTO_SERVER=TRUE"
).
getMetaData
().
getURL
();
logger
.
info
(
jdbcurl
);
HikariDataSource
ds
=
new
HikariDataSource
();
setupFeaturesTable
();
ds
.
setJdbcUrl
(
jdbcurl
);
ds
.
setUsername
(
"sa"
);
ds
.
setPassword
(
"sa"
);
...
...
@@ -48,10 +50,11 @@ public class DatabaseHandler {
ds
.
setMinimumIdle
(
coreCount
*
5
);
dataSource
=
new
DataSourceWrapper
(
ds
);
setupFeaturesTable
();
//Cleanup hook
Runtime
.
getRuntime
().
addShutdownHook
(
new
Thread
(
ds:
:
close
));
}
catch
(
Exception
e
)
{
//TODO: Localize Strings in this class
logger
.
fatal
(
"FATAL ERROR: Creation of embedded database failed!"
);
logger
.
fatal
(
e
.
getMessage
());
}
...
...
@@ -61,7 +64,7 @@ public class DatabaseHandler {
public
void
setupFeaturesTable
()
{
try
(
Connection
con
=
H2GISDBFactory
.
openSpatialDataBase
(
DB_NAME
))
{
try
(
Connection
con
=
dataSource
.
getConnection
(
))
{
try
(
PreparedStatement
dropPs
=
con
.
prepareStatement
(
"DROP TABLE IF EXISTS features"
)){
dropPs
.
executeUpdate
();
if
(
logger
.
isDebugEnabled
())
{
...
...
@@ -78,6 +81,7 @@ public class DatabaseHandler {
}
}
catch
(
SQLException
e
)
{
//TODO: Localize String
logger
.
fatal
(
"FATAL ERROR: Creation of CityDoctorModel database table failed!"
);
logger
.
fatal
(
e
.
getMessage
());
}
...
...
@@ -93,12 +97,8 @@ public class DatabaseHandler {
ps
.
setString
(
1
,
co
.
getGmlId
().
toString
());
String
bbox
=
BoundingBox
.
of
(
co
).
to2DWkt
();
ps
.
setString
(
2
,
bbox
);
if
(
co
.
isValidated
())
{
ps
.
setBoolean
(
4
,
co
.
hasAnyError
());
}
else
{
ps
.
setNull
(
4
,
java
.
sql
.
Types
.
BOOLEAN
);
}
ps
.
setBoolean
(
4
,
co
.
hasAnyError
());
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Attempting to serialize CityObject: {} "
,
co
);
}
...
...
@@ -114,6 +114,7 @@ public class DatabaseHandler {
}
}
}
catch
(
SQLException
e
)
{
//TODO: Localize String
logger
.
error
(
"Saving of city object {} to embedded database failed!"
,
co
.
getGmlId
());
logger
.
error
(
e
.
getMessage
());
}
...
...
@@ -123,7 +124,7 @@ public class DatabaseHandler {
// Id String for error logging
String
id
=
""
;
try
(
Connection
con
=
dataSource
.
getConnection
())
{
try
(
PreparedStatement
ps
=
con
.
prepareStatement
(
"MERGE INTO features VALUES (?, ?, ?,?)"
))
{
try
(
PreparedStatement
ps
=
con
.
prepareStatement
(
"MERGE INTO features VALUES (?, ?, ?,
?)"
))
{
con
.
setAutoCommit
(
false
);
for
(
Map
.
Entry
<
GmlId
,
CityObject
>
entry
:
map
.
entrySet
())
{
CityObject
co
=
entry
.
getValue
();
...
...
@@ -134,18 +135,15 @@ public class DatabaseHandler {
if
(
logger
.
isTraceEnabled
())
{
logger
.
trace
(
"Attempting to serialize CityObject: {} "
,
co
);
}
if
(
co
.
isValidated
())
{
ps
.
setBoolean
(
4
,
co
.
hasAnyError
());
}
else
{
ps
.
setNull
(
4
,
java
.
sql
.
Types
.
BOOLEAN
);
}
ps
.
setBoolean
(
4
,
co
.
hasAnyError
());
try
{
byte
[]
bytes
=
SerializationUtils
.
serialize
(
co
);
ByteArrayInputStream
bis
=
new
ByteArrayInputStream
(
bytes
);
ps
.
setBinaryStream
(
3
,
bis
,
bytes
.
length
);
ps
.
addBatch
();
}
catch
(
SerializationException
e
)
{
//TODO: Localize String
logger
.
error
(
"Serialization of CityObject {} failed"
,
co
.
getGmlId
());
logger
.
error
(
e
.
getMessage
());
}
...
...
@@ -154,11 +152,13 @@ public class DatabaseHandler {
con
.
commit
();
}
catch
(
SQLException
e
)
{
con
.
rollback
();
//TODO: Localize String
logger
.
error
(
"Batch-commit aborted: Saving of CityObject {} to embedded database critically failed!"
,
id
);
logger
.
error
(
e
.
getMessage
());
return
false
;
}
}
catch
(
SQLException
e
){
//TODO: Localize String
logger
.
error
(
"Connection to embedded database could not be opened!"
);
logger
.
error
(
e
.
getMessage
());
return
false
;
...
...
@@ -194,6 +194,7 @@ public class DatabaseHandler {
throw
new
RuntimeException
(
e
);
}
}
catch
(
SQLException
e
)
{
//TODO: Localize String
logger
.
error
(
"Loading of city object from embedded database failed!"
);
logger
.
error
(
e
.
getMessage
());
}
...
...
@@ -211,6 +212,7 @@ public class DatabaseHandler {
}
}
}
catch
(
SQLException
e
)
{
//TODO: Localize String
logger
.
error
(
"Fetching ids of all features with errors failed!"
);
logger
.
error
(
e
.
getMessage
());
}
...
...
@@ -225,6 +227,7 @@ public class DatabaseHandler {
cos
.
addAll
(
retrieveCityObjects
(
rs
));
}
}
catch
(
SQLException
e
)
{
//TODO: Localize String
logger
.
error
(
"Connection to database failed while trying to get all CityObjects!"
);
logger
.
debug
(
e
.
getMessage
());
}
...
...
@@ -241,6 +244,7 @@ public class DatabaseHandler {
}
}
}
catch
(
SQLException
e
)
{
//TODO: Localize String
logger
.
error
(
"Connection to database failed while trying to get all CityObjects!"
);
logger
.
debug
(
e
.
getMessage
());
}
...
...
@@ -266,6 +270,7 @@ public class DatabaseHandler {
}
}
}
catch
(
SQLException
e
)
{
//TODO: Localize String
logger
.
error
(
"Connection to database failed while trying to get buffer intersecting objects!"
);
logger
.
debug
(
e
.
getMessage
());
}
...
...
@@ -291,6 +296,7 @@ public class DatabaseHandler {
}
}
}
catch
(
SQLException
e
)
{
//TODO: Localize String
logger
.
error
(
"Connection to database failed while trying to get bbox intersecting objects!"
);
logger
.
debug
(
e
.
getMessage
());
}
...
...
@@ -309,6 +315,7 @@ public class DatabaseHandler {
}
}
}
catch
(
SQLException
e
)
{
//TODO: Localize String
logger
.
error
(
"Connection to database failed while trying to get bbox intersecting objects!"
);
logger
.
debug
(
e
.
getMessage
());
}
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/database/FeatureCache.java
View file @
6607295e
...
...
@@ -5,7 +5,6 @@ import com.github.benmanes.caffeine.cache.LoadingCache;
import
com.github.benmanes.caffeine.cache.RemovalCause
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.GmlId
;
import
de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
...
...
@@ -115,18 +114,24 @@ public class FeatureCache implements CityObjectCache{
return
handler
.
getIdsOfAllCityObjectsWithErrors
();
}
/**
* Synchronizes cache and database
*/
public
void
synchronize
(){
HashMap
<
GmlId
,
CityObject
>
cacheContent
=
new
HashMap
<>(
cache
.
asMap
());
boolean
success
=
handler
.
tryMarshallCityObjectMap
(
cacheContent
);
if
(!
success
)
{
logger
.
trace
(
"Batch marshalling failed, falling back to one-by-one marshalling"
);
// Batch marshalling failed, marshall them one-by-one
for
(
Map
.
Entry
<
GmlId
,
CityObject
>
entry
:
cacheContent
.
entrySet
())
{
handler
.
marshallCityObject
(
entry
.
getValue
());
}
}
}
public
void
finishParsing
()
{
if
(!
parsingFinished
)
{
HashMap
<
GmlId
,
CityObject
>
cacheContent
=
new
HashMap
<>(
cache
.
asMap
());
boolean
success
=
handler
.
tryMarshallCityObjectMap
(
cacheContent
);
if
(!
success
)
{
logger
.
trace
(
"Batch marshalling failed, falling back to one-by-one marshalling"
);
// Batch marshalling failed, marshall them one-by-one
for
(
Map
.
Entry
<
GmlId
,
CityObject
>
entry
:
cacheContent
.
entrySet
())
{
handler
.
marshallCityObject
(
entry
.
getValue
());
}
}
synchronize
();
parsingFinished
=
true
;
}
}
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
View file @
6607295e
...
...
@@ -446,6 +446,7 @@ public class CityGmlParser {
List
<
AbstractCityObject
>
acos
=
new
ArrayList
<>();
CityModel
cgmlModel
=
null
;
CityDoctorModel
cdModel
=
mapper
.
getModel
();
cdModel
.
getCache
().
resetCache
();
List
<
AbstractCityObject
>
queuedObjects
=
new
ArrayList
<>();
while
(
reader
.
hasNext
())
{
AbstractFeature
chunk
=
reader
.
next
();
...
...
CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization.properties
View file @
6607295e
...
...
@@ -86,7 +86,7 @@ OpenFileDialog.xmlValidationLabel=Use XML Validation
Checker.failXml
=
Failed to write XML Error Report.
Checker.failPdf
=
Failed to write PDF Report.
Checker.checksFinished
=
Finished executing checks
Checker.schematronValidation
=
Starting
Schematron
validation
Checker.schematronValidation
=
Schematron
-
validation
thread started
Checker.finishedSchematron
=
Finished Schematron validation
Checker.failReports
=
Failed to write reports.
Checker.checkFeature
=
Checking feature: {}
...
...
CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java
View file @
6607295e
...
...
@@ -28,6 +28,7 @@ import de.hft.stuttgart.citydoctor2.checks.CheckPrototype;
import
de.hft.stuttgart.citydoctor2.checks.Checks
;
import
de.hft.stuttgart.citydoctor2.checks.SvrlContentHandler
;
import
de.hft.stuttgart.citydoctor2.checks.util.FeatureCheckedListener
;
import
de.hft.stuttgart.citydoctor2.database.CacheManager
;
import
de.hft.stuttgart.citydoctor2.database.CityObjectCache
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
...
...
@@ -693,6 +694,7 @@ public class Checker {
String
msg
=
String
.
format
(
"Checker could not load %d/%.0f features (%.2f%%)"
,
missing
,
featureSum
,
(
missing
/
featureSum
)
*
100
);
logger
.
warn
(
msg
);
}
CacheManager
.
synchronizeCache
();
// model.preCacheShownFeatures();
}
catch
(
InterruptedException
e
)
{
throw
new
RuntimeException
(
e
);
...
...
CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CityDoctorController.java
View file @
6607295e
...
...
@@ -6,6 +6,7 @@ import de.hft.stuttgart.citydoctor2.check.Checker;
import
de.hft.stuttgart.citydoctor2.check.ErrorId
;
import
de.hft.stuttgart.citydoctor2.check.ValidationConfiguration
;
import
de.hft.stuttgart.citydoctor2.check.error.SchematronError
;
import
de.hft.stuttgart.citydoctor2.database.CacheManager
;
import
de.hft.stuttgart.citydoctor2.datastructure.*
;
import
de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException
;
import
de.hft.stuttgart.citydoctor2.gui.table.ErrorStat
;
...
...
@@ -1386,8 +1387,11 @@ public class CityDoctorController {
mainWindow
.
resetSearchBar
();
root
.
getChildren
().
clear
();
resetFeatureChunks
();
List
<
GmlId
>
foundBuildings
=
new
ArrayList
<>();
model
.
getBuildings
().
filter
(
Checkable:
:
containsAnyError
).
forEach
(
co
->
foundBuildings
.
add
(
co
.
getGmlId
()));
List
<
GmlId
>
foundBuildings
=
model
.
getCache
().
getErrorFeatureIds
();
List
<
GmlId
>
idList
=
model
.
getBuildingIds
();
foundBuildings
.
removeIf
(
gmlId
->
(!
idList
.
contains
(
gmlId
)));
// model.getBuildings().filter(Checkable::containsAnyError).forEach(co -> foundBuildings.add(co.getGmlId()));
Supplier
<
Stream
<
Building
>>
supply
=
()
->
model
.
getCache
().
getStream
(
foundBuildings
).
map
(
co
->
(
Building
)
co
);
buildBuildingTreeFromList
(
supply
,
root
);
updateTree
(
root
);
...
...
@@ -1406,8 +1410,11 @@ public class CityDoctorController {
mainWindow
.
resetSearchBar
();
root
.
getChildren
().
clear
();
resetFeatureChunks
();
List
<
GmlId
>
foundVegetation
=
new
ArrayList
<>();
model
.
getVegetation
().
filter
(
Checkable:
:
containsAnyError
).
forEach
(
co
->
foundVegetation
.
add
(
co
.
getGmlId
()));
List
<
GmlId
>
foundVegetation
=
model
.
getCache
().
getErrorFeatureIds
();
List
<
GmlId
>
idList
=
model
.
getVegetationIds
();
foundVegetation
.
removeIf
(
gmlId
->
(!
idList
.
contains
(
gmlId
)));
// model.getVegetation().filter(Checkable::containsAnyError).forEach(co -> foundVegetation.add(co.getGmlId()));
Supplier
<
Stream
<
Vegetation
>>
supply
=
()
->
model
.
getCache
().
getStream
(
foundVegetation
).
map
(
co
->
(
Vegetation
)
co
);
buildVegetationTreeFromList
(
supply
,
root
);
updateTree
(
root
);
...
...
@@ -1426,8 +1433,11 @@ public class CityDoctorController {
mainWindow
.
resetSearchBar
();
root
.
getChildren
().
clear
();
resetFeatureChunks
();
List
<
GmlId
>
foundBridge
=
new
ArrayList
<>();
model
.
getBridges
().
filter
(
Checkable:
:
containsAnyError
).
forEach
(
co
->
foundBridge
.
add
(
co
.
getGmlId
()));
List
<
GmlId
>
foundBridge
=
model
.
getCache
().
getErrorFeatureIds
();
List
<
GmlId
>
idList
=
model
.
getBridgeIds
();
foundBridge
.
removeIf
(
gmlId
->
(!
idList
.
contains
(
gmlId
)));
// model.getBridges().filter(Checkable::containsAnyError).forEach(co -> foundBridge.add(co.getGmlId()));
Supplier
<
Stream
<
BridgeObject
>>
supply
=
()
->
model
.
getCache
().
getStream
(
foundBridge
).
map
(
co
->
(
BridgeObject
)
co
);
buildBridgeTreeFromList
(
supply
,
root
);
updateTree
(
root
);
...
...
@@ -1446,8 +1456,11 @@ public class CityDoctorController {
mainWindow
.
resetSearchBar
();
root
.
getChildren
().
clear
();
resetFeatureChunks
();
List
<
GmlId
>
foundLand
=
new
ArrayList
<>();
model
.
getLand
().
filter
(
Checkable:
:
containsAnyError
).
forEach
(
co
->
foundLand
.
add
(
co
.
getGmlId
()));
List
<
GmlId
>
foundLand
=
model
.
getCache
().
getErrorFeatureIds
();
List
<
GmlId
>
idList
=
model
.
getLandIds
();
foundLand
.
removeIf
(
gmlId
->
(!
idList
.
contains
(
gmlId
)));
// model.getLand().filter(Checkable::containsAnyError).forEach(co -> foundLand.add(co.getGmlId()));
Supplier
<
Stream
<
CityObject
>>
supply
=
()
->
model
.
getCache
().
getStream
(
foundLand
).
map
(
co
->
(
CityObject
)
co
);
buildLandTreeFromList
(
supply
,
root
);
updateTree
(
root
);
...
...
@@ -1466,8 +1479,11 @@ public class CityDoctorController {
mainWindow
.
resetSearchBar
();
root
.
getChildren
().
clear
();
resetFeatureChunks
();
List
<
GmlId
>
foundCityFurniture
=
new
ArrayList
<>();
model
.
getCityFurniture
().
filter
(
Checkable:
:
containsAnyError
).
forEach
(
co
->
foundCityFurniture
.
add
(
co
.
getGmlId
()));
List
<
GmlId
>
foundCityFurniture
=
model
.
getCache
().
getErrorFeatureIds
();
List
<
GmlId
>
idList
=
model
.
getCityFurnitureIds
();
foundCityFurniture
.
removeIf
(
gmlId
->
(!
idList
.
contains
(
gmlId
)));
// model.getCityFurniture().filter(Checkable::containsAnyError).forEach(co -> foundCityFurniture.add(co.getGmlId()));
Supplier
<
Stream
<
CityFurniture
>>
supply
=
()
->
model
.
getCache
().
getStream
(
foundCityFurniture
).
map
(
co
->
(
CityFurniture
)
co
);
buildCityFurnitureTreeFromList
(
supply
,
root
);
updateTree
(
root
);
...
...
@@ -1486,8 +1502,11 @@ public class CityDoctorController {
mainWindow
.
resetSearchBar
();
root
.
getChildren
().
clear
();
resetFeatureChunks
();
List
<
GmlId
>
foundGenericCityObjects
=
new
ArrayList
<>();
model
.
getGenericCityObjects
().
filter
(
Checkable:
:
containsAnyError
).
forEach
(
co
->
foundGenericCityObjects
.
add
(
co
.
getGmlId
()));
List
<
GmlId
>
foundGenericCityObjects
=
model
.
getCache
().
getErrorFeatureIds
();
List
<
GmlId
>
idList
=
model
.
getGenericCityObjectIds
();
foundGenericCityObjects
.
removeIf
(
gmlId
->
(!
idList
.
contains
(
gmlId
)));
// model.getGenericCityObjects().filter(Checkable::containsAnyError).forEach(co -> foundGenericCityObjects.add(co.getGmlId()));
Supplier
<
Stream
<
GenericCityObject
>>
supply
=
()
->
model
.
getCache
().
getStream
(
foundGenericCityObjects
).
map
(
co
->
(
GenericCityObject
)
co
);
buildGenericCityObjectTreeFromList
(
supply
,
root
);
updateTree
(
root
);
...
...
@@ -1506,8 +1525,11 @@ public class CityDoctorController {
mainWindow
.
resetSearchBar
();
root
.
getChildren
().
clear
();
resetFeatureChunks
();
List
<
GmlId
>
foundTransportation
=
new
ArrayList
<>();
model
.
getTransportation
().
filter
(
Checkable:
:
containsAnyError
).
forEach
(
co
->
foundTransportation
.
add
(
co
.
getGmlId
()));
List
<
GmlId
>
foundTransportation
=
model
.
getCache
().
getErrorFeatureIds
();
List
<
GmlId
>
idList
=
model
.
getTransportationIds
();
foundTransportation
.
removeIf
(
gmlId
->
(!
idList
.
contains
(
gmlId
)));
// model.getTransportation().filter(Checkable::containsAnyError).forEach(co -> foundTransportation.add(co.getGmlId()));
Supplier
<
Stream
<
TransportationObject
>>
supply
=
()
->
model
.
getCache
().
getStream
(
foundTransportation
).
map
(
co
->
(
TransportationObject
)
co
);
buildTransportationTreeFromList
(
supply
,
root
);
updateTree
(
root
);
...
...
@@ -1526,8 +1548,11 @@ public class CityDoctorController {
mainWindow
.
resetSearchBar
();
root
.
getChildren
().
clear
();
resetFeatureChunks
();
List
<
GmlId
>
foundTunnel
=
new
ArrayList
<>();
model
.
getTunnels
().
filter
(
Checkable:
:
containsAnyError
).
forEach
(
co
->
foundTunnel
.
add
(
co
.
getGmlId
()));
List
<
GmlId
>
foundTunnel
=
model
.
getCache
().
getErrorFeatureIds
();
List
<
GmlId
>
idList
=
model
.
getTunnelIds
();
foundTunnel
.
removeIf
(
gmlId
->
(!
idList
.
contains
(
gmlId
)));
// model.getTunnels().filter(Checkable::containsAnyError).forEach(co -> foundTunnel.add(co.getGmlId()));
Supplier
<
Stream
<
Tunnel
>>
supply
=
()
->
model
.
getCache
().
getStream
(
foundTunnel
).
map
(
co
->
(
Tunnel
)
co
);
buildTunnelTreeFromList
(
supply
,
root
);
updateTree
(
root
);
...
...
@@ -1547,8 +1572,11 @@ public class CityDoctorController {
mainWindow
.
resetSearchBar
();
root
.
getChildren
().
clear
();
resetFeatureChunks
();
List
<
GmlId
>
foundWater
=
new
ArrayList
<>();
model
.
getWater
().
filter
(
Checkable:
:
containsAnyError
).
forEach
(
co
->
foundWater
.
add
(
co
.
getGmlId
()));
List
<
GmlId
>
foundWater
=
model
.
getCache
().
getErrorFeatureIds
();
List
<
GmlId
>
idList
=
model
.
getWaterIds
();
foundWater
.
removeIf
(
gmlId
->
(!
idList
.
contains
(
gmlId
)));
// model.getWater().filter(Checkable::containsAnyError).forEach(co -> foundWater.add(co.getGmlId()));
Supplier
<
Stream
<
WaterObject
>>
supply
=
()
->
model
.
getCache
().
getStream
(
foundWater
).
map
(
co
->
(
WaterObject
)
co
);
buildWaterTreeFromList
(
supply
,
root
);
updateTree
(
root
);
...
...
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