Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Eric Duminil
RegionChooser
Commits
05d384c8
Commit
05d384c8
authored
Oct 19, 2022
by
Eric Duminil
Browse files
Merge branch 'experimental/refactor' into develop
parents
5a39d8db
652df34d
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/main/java/eu/simstadt/regionchooser/RegionChooserBrowser.java
View file @
05d384c8
...
@@ -49,12 +49,8 @@ public JavaScriptFXBridge() {
...
@@ -49,12 +49,8 @@ public JavaScriptFXBridge() {
/**
/**
* Launches a background thread in which the hull gets extracted for every CityGML file. The hull gets sent back
* Launches a background thread in which the hull gets extracted for every CityGML file. The hull gets sent back
* to the JS app in order to be displayed.
* to the JS app in order to be displayed.
*
* NOTE: To be very honest, I don't really understand concurrency in JavaFX. Eric
*
*/
*/
public
void
refreshHulls
()
{
public
void
refreshHulls
()
{
//NOTE: Could add progress bar?
Task
<
Void
>
task
=
new
Task
<
Void
>()
{
Task
<
Void
>
task
=
new
Task
<
Void
>()
{
@Override
@Override
public
Void
call
()
throws
IOException
{
public
Void
call
()
throws
IOException
{
...
@@ -76,27 +72,35 @@ public Void call() throws IOException {
...
@@ -76,27 +72,35 @@ public Void call() throws IOException {
}
}
/**
/**
* This method is called from Javascript, with a prepared wktPolygon written in local coordinates.
* This method is called from Javascript, with a prepared wktPolygon written in local coordinates. Executes it in
* the background to avoid freezing the GUI
*/
*/
public
int
downloadRegionFromCityGMLs
(
String
wktPolygon
,
String
project
,
String
csvCitygmls
,
String
srsName
)
public
void
downloadRegionFromCityGMLs
(
String
wktPolygon
,
String
project
,
String
csvCitygmls
,
String
srsName
)
{
throws
IOException
,
ParseException
,
XPathParseException
,
NavException
{
// It doesn't seem possible to pass arrays or list from JS to Java. So csvCitygmls contains names separated by ;
// It doesn't seem possible to pass arrays or list from JS to Java. So csvCitygmls contains names separated by ;
Path
[]
paths
=
Stream
.
of
(
csvCitygmls
.
split
(
";"
)).
map
(
s
->
citygmlPath
(
project
,
s
)).
toArray
(
Path
[]::
new
);
Path
[]
paths
=
Stream
.
of
(
csvCitygmls
.
split
(
";"
)).
map
(
s
->
citygmlPath
(
project
,
s
)).
toArray
(
Path
[]::
new
);
String
proposedName
=
csvCitygmls
.
replace
(
";"
,
"_"
).
replace
(
".gml"
,
""
)
+
".gml"
;
String
proposedName
=
csvCitygmls
.
replace
(
";"
,
"_"
).
replace
(
".gml"
,
""
)
+
".gml"
;
File
outputFile
=
selectSaveFileWithDialog
(
project
,
proposedName
,
"part"
);
File
outputFile
=
selectSaveFileWithDialog
(
project
,
proposedName
,
"part"
);
if
(
outputFile
==
null
)
{
if
(
outputFile
==
null
)
{
return
-
1
;
return
;
}
}
int
count
;
Task
<
Integer
>
downloadTask
=
new
Task
<
Integer
>()
{
try
(
BufferedWriter
gmlWriter
=
Files
.
newBufferedWriter
(
outputFile
.
toPath
()))
{
@Override
count
=
RegionExtractor
.
selectRegionDirectlyFromCityGML
(
wktPolygon
,
srsName
,
gmlWriter
,
paths
);
public
Integer
call
()
throws
IOException
,
XPathParseException
,
NavException
,
ParseException
{
}
int
count
=
-
1
;
LOGGER
.
info
(
outputFile
+
" has been written"
);
try
(
BufferedWriter
gmlWriter
=
Files
.
newBufferedWriter
(
outputFile
.
toPath
()))
{
return
count
;
count
=
RegionExtractor
.
selectRegionDirectlyFromCityGML
(
wktPolygon
,
srsName
,
gmlWriter
,
paths
);
}
LOGGER
.
info
(
outputFile
+
" has been written"
);
return
count
;
}
};
downloadTask
.
setOnRunning
(
e
->
jsApp
.
call
(
"downloadStart"
));
downloadTask
.
setOnSucceeded
(
e
->
jsApp
.
call
(
"downloadFinished"
,
e
.
getSource
().
getValue
()));
new
Thread
(
downloadTask
).
start
();
}
}
...
...
src/main/java/eu/simstadt/regionchooser/RegionExtractor.java
View file @
05d384c8
...
@@ -88,7 +88,7 @@ static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Wr
...
@@ -88,7 +88,7 @@ static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Wr
LOGGER
.
warning
(
"No building found in the selected region."
);
LOGGER
.
warning
(
"No building found in the selected region."
);
}
}
LOGGER
.
info
(
"Buildings found in selected region "
+
foundBuildingsCount
);
LOGGER
.
info
(
"Buildings found in selected region
:
"
+
foundBuildingsCount
);
//NOTE: This could be a problem if header starts with <core:CityModel> and footer ends with </CityModel>
//NOTE: This could be a problem if header starts with <core:CityModel> and footer ends with </CityModel>
sb
.
append
(
citygml
.
getFooter
());
sb
.
append
(
citygml
.
getFooter
());
return
foundBuildingsCount
;
return
foundBuildingsCount
;
...
...
src/main/resources/eu/simstadt/regionchooser/website/script/simstadt_openlayers.js
View file @
05d384c8
...
@@ -11,11 +11,9 @@ const regionChooser = (function(){
...
@@ -11,11 +11,9 @@ const regionChooser = (function(){
const
dataPanel
=
$
(
'
#dataPanel
'
);
const
dataPanel
=
$
(
'
#dataPanel
'
);
const
wgs84Sphere
=
new
ol
.
Sphere
(
6378137
);
const
wgs84Sphere
=
new
ol
.
Sphere
(
6378137
);
var
features_by_project
;
var
features_by_project
;
var
gmlId
;
publicScope
.
init
=
function
(){
publicScope
.
init
=
function
(){
//NOTE: Only called from JavaFX. At startup, or when Repo has been changed.
//NOTE: Only called from JavaFX. At startup, or when Repo has been changed.
gmlId
=
0
;
kml_source
.
clear
();
kml_source
.
clear
();
document
.
getElementById
(
"
select_repository
"
).
style
.
visibility
=
"
visible
"
;
document
.
getElementById
(
"
select_repository
"
).
style
.
visibility
=
"
visible
"
;
}
}
...
@@ -49,7 +47,6 @@ const regionChooser = (function(){
...
@@ -49,7 +47,6 @@ const regionChooser = (function(){
publicScope
.
addCityGmlHull
=
function
(
kmlString
)
{
publicScope
.
addCityGmlHull
=
function
(
kmlString
)
{
options
=
{
featureProjection
:
ol
.
proj
.
get
(
'
EPSG:3857
'
)};
options
=
{
featureProjection
:
ol
.
proj
.
get
(
'
EPSG:3857
'
)};
feature
=
kmlFormat
.
readFeature
(
kmlString
,
options
);
feature
=
kmlFormat
.
readFeature
(
kmlString
,
options
);
feature
.
setId
(
gmlId
++
);
kml_source
.
addFeature
(
feature
);
kml_source
.
addFeature
(
feature
);
dataPanel
.
append
(
'
.
'
);
dataPanel
.
append
(
'
.
'
);
srsName
=
feature
.
get
(
"
srsName
"
);
srsName
=
feature
.
get
(
"
srsName
"
);
...
@@ -151,26 +148,40 @@ const regionChooser = (function(){
...
@@ -151,26 +148,40 @@ const regionChooser = (function(){
var
intersectionArea
=
intersection
.
getGeometry
().
getArea
();
var
intersectionArea
=
intersection
.
getGeometry
().
getArea
();
var
citygml_percentage
=
Math
.
round
(
intersectionArea
/
feature
[
"
area
"
]
*
100
);
var
citygml_percentage
=
Math
.
round
(
intersectionArea
/
feature
[
"
area
"
]
*
100
);
var
sketch_percentage
=
Math
.
round
(
intersectionArea
/
polygonArea
*
100
);
var
sketch_percentage
=
Math
.
round
(
intersectionArea
/
polygonArea
*
100
);
var
id
=
feature
.
getId
();
intersections
.
addFeature
(
intersection
);
intersections
.
addFeature
(
intersection
);
var
link
=
'
<li onmouseover="regionChooser.highlightPolygon(
'
+
id
+
'
)" onmouseout="regionChooser.resetHighlight(
'
+
id
+
'
)">
'
;
link
+=
'
<input type="checkbox" id="citygml_
'
+
feature
.
getId
()
+
'
" class="select_citygml" onclick="regionChooser.isDownloadPossible();">
'
li
=
document
.
createElement
(
'
li
'
);
+
'
<label for="citygml_
'
+
feature
.
getId
()
+
'
">
'
+
feature
[
'
name
'
]
+
'
</label>
'
;
li
.
feature
=
feature
;
link
+=
"
(
"
+
citygml_percentage
+
"
%
"
;
li
.
onmouseover
=
function
(){
regionChooser
.
highlightPolygon
(
this
.
feature
)
};
li
.
onmouseout
=
function
(){
regionChooser
.
resetHighlight
(
this
.
feature
)
};
let
label
=
li
.
appendChild
(
document
.
createElement
(
'
label
'
));
var
text
=
feature
.
name
;
let
checkbox
=
document
.
createElement
(
'
input
'
);
checkbox
.
type
=
'
checkbox
'
checkbox
.
className
=
"
select_citygml
"
;
checkbox
.
feature
=
feature
;
checkbox
.
setAttribute
(
'
onclick
'
,
"
regionChooser.isDownloadPossible()
"
);
text
+=
"
(
"
+
citygml_percentage
+
"
%
"
;
if
(
sketch_percentage
==
100
)
{
if
(
sketch_percentage
==
100
)
{
link
+=
"
, all inside
"
;
text
+=
"
, all inside
"
;
}
}
dataPanel
.
append
(
link
+
"
)
\n
"
);
label
.
textContent
=
text
+
"
)
\n
"
;
label
.
prepend
(
checkbox
);
// append to DOM element, not to jQuery object
dataPanel
[
0
].
appendChild
(
li
);
}
}
publicScope
.
highlightPolygon
=
function
(
i
)
{
publicScope
.
highlightPolygon
=
function
(
feature
)
{
var
feature
=
kml_source
.
getFeatureById
(
i
);
feature
.
setStyle
(
styles
.
highlighted
);
feature
.
setStyle
(
styles
.
highlighted
);
}
}
publicScope
.
resetHighlight
=
function
(
i
)
{
publicScope
.
resetHighlight
=
function
(
feature
)
{
var
feature
=
kml_source
.
getFeatureById
(
i
);
refreshStyle
(
feature
);
refreshStyle
(
feature
);
}
}
...
@@ -184,13 +195,15 @@ const regionChooser = (function(){
...
@@ -184,13 +195,15 @@ const regionChooser = (function(){
publicScope
.
isDownloadPossible
=
function
(){
publicScope
.
isDownloadPossible
=
function
(){
kml_source
.
getFeatures
().
forEach
(
f
=>
refreshStyle
(
f
,
"
original
"
));
kml_source
.
getFeatures
().
forEach
(
f
=>
refreshStyle
(
f
,
"
original
"
));
//TODO: Dry
selectedFeatures
=
getSelectedGMLs
();
var
checkedBoxes
=
Array
.
from
(
document
.
querySelectorAll
(
"
input.select_citygml
"
)).
filter
(
c
=>
c
.
checked
);
var
checkbox_ids
=
checkedBoxes
.
map
(
c
=>
c
.
id
);
var
features
=
getCheckedPolygons
(
checkbox_ids
);
features
.
forEach
(
f
=>
refreshStyle
(
f
,
"
selected
"
));
document
.
getElementById
(
"
download_region_button
"
).
disabled
=
(
checkedBoxes
.
length
==
0
);
selectedFeatures
.
forEach
(
f
=>
refreshStyle
(
f
,
"
selected
"
));
document
.
getElementById
(
"
download_region_button
"
).
disabled
=
(
selectedFeatures
.
length
==
0
);
}
function
getSelectedGMLs
(){
return
Array
.
from
(
document
.
querySelectorAll
(
"
input.select_citygml
"
)).
filter
(
c
=>
c
.
checked
).
map
(
c
=>
c
.
feature
);
}
}
function
findIntersection
(
feature
,
polygon
)
{
function
findIntersection
(
feature
,
polygon
)
{
...
@@ -230,17 +243,28 @@ const regionChooser = (function(){
...
@@ -230,17 +243,28 @@ const regionChooser = (function(){
dataPanel
.
append
(
text
+
"
<br/>
\n
"
);
dataPanel
.
append
(
text
+
"
<br/>
\n
"
);
}
}
getCheckedPolygons
=
function
(
checkbox_ids
){
publicScope
.
downloadStart
=
function
(){
return
checkbox_ids
.
map
(
checkbox_id
=>
{
document
.
getElementById
(
"
download_region_button
"
).
disabled
=
true
;
var
i
=
Number
(
checkbox_id
.
replace
(
"
citygml_
"
,
""
));
document
.
documentElement
.
className
=
'
wait
'
;
return
kml_source
.
getFeatureById
(
i
);
dataPanel
.
prepend
(
"
<h2 id='download_start' class='ok'>Starting to extract region...</h2><br/>
\n
"
);
})
}
}
publicScope
.
downloadRegionFromCityGMLs
=
function
(
checkbox_ids
)
{
publicScope
.
downloadFinished
=
function
(
count
){
//FIXME: Somehow, no feedback comes after large files are downloaded. :(
document
.
documentElement
.
className
=
''
;
// Stop waiting
var
features
=
getCheckedPolygons
(
checkbox_ids
);
document
.
getElementById
(
"
download_start
"
).
remove
();
if
(
count
>
0
){
dataPanel
.
prepend
(
"
<h2 class='ok'>Done! (
"
+
count
+
"
buildings found) </h2><br/>
\n
"
);
}
else
{
dataPanel
.
prepend
(
"
<h2 class='error'>No building has been found in this region</h2><br/>
\n
"
);
}
var
button
=
document
.
getElementById
(
"
download_region_button
"
);
if
(
button
){
// Region might have been modified since download start
button
.
disabled
=
false
;
}
}
publicScope
.
downloadFromSelectedCityGMLs
=
function
()
{
var
features
=
getSelectedGMLs
();
var
project
=
features
[
0
].
get
(
"
project
"
);
var
project
=
features
[
0
].
get
(
"
project
"
);
var
srsName
=
features
[
0
].
get
(
"
srsName
"
);
var
srsName
=
features
[
0
].
get
(
"
srsName
"
);
...
@@ -253,38 +277,15 @@ const regionChooser = (function(){
...
@@ -253,38 +277,15 @@ const regionChooser = (function(){
dataPanel
.
prepend
(
"
<h2 class='error'>Sorry, the CityGML files should all be written with the same coordinate system.</h2><br/>
\n
"
);
dataPanel
.
prepend
(
"
<h2 class='error'>Sorry, the CityGML files should all be written with the same coordinate system.</h2><br/>
\n
"
);
}
}
document
.
documentElement
.
className
=
'
wait
'
;
var
citygmlNames
=
features
.
map
(
f
=>
f
.
get
(
"
name
"
));
var
citygmlNames
=
features
.
map
(
f
=>
f
.
get
(
"
name
"
));
// Waiting 100ms in order to let the cursor change
if
(
proj4
.
defs
(
srsName
)){
setTimeout
(
function
()
{
console
.
log
(
"
Selected region is written in
"
+
srsName
+
"
coordinate system.
"
);
var
start
=
new
Date
().
getTime
();
fxapp
.
downloadRegionFromCityGMLs
(
sketchAsWKT
(
srsName
),
project
,
citygmlNames
.
join
(
"
;
"
),
srsName
);
if
(
proj4
.
defs
(
srsName
)){
}
else
{
console
.
log
(
"
Selected region is written in
"
+
srsName
+
"
coordinate system.
"
);
var
msg
=
"
ERROR : Unknown coordinate system :
\"
"
+
srsName
+
"
\"
. Cannot extract any region
"
;
try
{
console
.
log
(
msg
);
var
count
=
fxapp
.
downloadRegionFromCityGMLs
(
sketchAsWKT
(
srsName
),
project
,
citygmlNames
.
join
(
"
;
"
),
srsName
);
dataPanel
.
append
(
msg
+
"
<br/>
\n
"
);
if
(
count
==
-
1
){
}
console
.
log
(
"
No output file has been selected.
"
);
}
else
{
dataPanel
.
prepend
(
"
<h2 class='ok'>Done! (
"
+
count
+
"
buildings found) </h2><br/>
\n
"
);
}
}
catch
(
e
)
{
console
.
warn
(
"
ERROR :
"
+
e
);
dataPanel
.
prepend
(
"
<h2 class='error'>Some problem occured!</h2><br/>
\n
"
);
}
var
end
=
new
Date
().
getTime
();
var
time
=
end
-
start
;
console
.
log
(
'
Download Execution time:
'
+
(
time
/
1000
).
toFixed
(
3
)
+
'
s
'
);
setTimeout
(
function
()
{
document
.
getElementById
(
"
download_region_button
"
).
disabled
=
false
;
document
.
documentElement
.
className
=
''
;
// Stop waiting
},
100
);
}
else
{
var
msg
=
"
ERROR : Unknown coordinate system :
\"
"
+
srsName
+
"
\"
. Cannot extract any region
"
;
console
.
log
(
msg
);
dataPanel
.
append
(
msg
+
"
<br/>
\n
"
);
}
},
100
);
}
}
function
displayInfo
()
{
function
displayInfo
()
{
...
@@ -328,6 +329,7 @@ const regionChooser = (function(){
...
@@ -328,6 +329,7 @@ const regionChooser = (function(){
}
finally
{
}
finally
{
displayHelp
();
displayHelp
();
document
.
documentElement
.
className
=
''
;
// Stop waiting
document
.
documentElement
.
className
=
''
;
// Stop waiting
kml_source
.
getFeatures
().
forEach
(
f
=>
refreshStyle
(
f
,
"
original
"
));
draw
.
setActive
(
true
);
draw
.
setActive
(
true
);
drawnLayer
.
getFeatures
().
clear
();
drawnLayer
.
getFeatures
().
clear
();
intersections
.
clear
();
intersections
.
clear
();
...
@@ -383,19 +385,6 @@ const regionChooser = (function(){
...
@@ -383,19 +385,6 @@ const regionChooser = (function(){
console
.
log
(
"
Ready!
"
);
console
.
log
(
"
Ready!
"
);
}
}
publicScope
.
downloadFromSelectedCityGMLs
=
function
()
{
document
.
getElementById
(
"
download_region_button
"
).
disabled
=
true
;
var
checkedBoxes
=
Array
.
from
(
document
.
querySelectorAll
(
"
input.select_citygml
"
)).
filter
(
c
=>
c
.
checked
);
// CheckBoxes isn't empty, because otherwise the button cannot be clicked.
var
checkbox_ids
=
checkedBoxes
.
map
(
c
=>
c
.
id
);
var
features
=
getCheckedPolygons
(
checkbox_ids
);
features
.
forEach
(
f
=>
f
.
setStyle
(
utils
.
polygon_style
(
"
#ffff00
"
,
0.8
)));
publicScope
.
downloadRegionFromCityGMLs
(
checkedBoxes
.
map
(
c
=>
c
.
id
));
}
publicScope
.
selectAllOrNone
=
function
(
allOrNone
)
{
publicScope
.
selectAllOrNone
=
function
(
allOrNone
)
{
document
.
querySelectorAll
(
"
input.select_citygml
"
).
forEach
(
c
=>
c
.
checked
=
allOrNone
);
document
.
querySelectorAll
(
"
input.select_citygml
"
).
forEach
(
c
=>
c
.
checked
=
allOrNone
);
publicScope
.
isDownloadPossible
();
publicScope
.
isDownloadPossible
();
...
...
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