-
Notifications
You must be signed in to change notification settings - Fork 123
New sample: Apply mosiac rule to rasters #614
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Merge branch 'master' into dev
Merge pull request master into dev (following sketch on map sample implementation)
Merge branch "master" into "dev"
Merge master into dev following FeatureCollectionLayerQuery implementation
Update README to alert Java 11 users to potential exceptions which may occur when running the project. Providing a suggested workaround from the OpenJavaFX docs.
Update README.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @sclaridge , this looks great.
I've made a few suggestions for re-ordering and re-wording of comments.
One interesting thing to look at together would be the use of the member variable mosaicRule
, and whether we need to set that explicitly to the imageServiceRaster
every time we change it's contents.
Unfortunately I am not able to test this right now as the service seems to be down. Let's discuss it over a call and see if there's any improvements to make
@@ -0,0 +1,43 @@ | |||
# Apply mosaic rule to rasters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make sense to keep raster
as singular throughout, unless there's a mechanism to apply a rule to a whole group of rasters in bulk?
However if the design for this is already finalised, just disregard this comment 😁
# Apply mosaic rule to rasters | |
# Apply mosaic rule to raster |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The design has been finalized, so I'll stick with rasters!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Jon here, though checking the design I now understand why it's plural:
Mosaic rules are applied to mosaic datasets, which are a mesh of several rasters managed together as one
// create a combo box | ||
ComboBox<String> comboBox = new ComboBox<>(); | ||
comboBox.setMaxWidth(Double.MAX_VALUE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can be a bit more specific and name this mosaicRuleComboBox
?
String imageServiceURL = "https://sampleserver7.arcgisonline.com/server/rest/services/amberg_germany/ImageServer"; | ||
ImageServiceRaster imageServiceRaster = new ImageServiceRaster(imageServiceURL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we just put the URL right in the constructor to avoid making a String
variable only used once?
String imageServiceURL = "https://sampleserver7.arcgisonline.com/server/rest/services/amberg_germany/ImageServer"; | |
ImageServiceRaster imageServiceRaster = new ImageServiceRaster(imageServiceURL); | |
ImageServiceRaster imageServiceRaster = | |
new ImageServiceRaster("https://sampleserver7.arcgisonline.com/server/rest/services/amberg_germany/ImageServer"); |
comboBox.getItems().addAll("Default", "Northwest", "Center", "By attribute", "Lock raster"); | ||
|
||
// set the default combo box value | ||
comboBox.setValue("Default"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've never actually seen .setValue
. Should maybe double check that it's doing the same as comboBox.getSelectionModel().select(0);
?
// add the mosaic rules to the combo box | ||
comboBox.getItems().addAll("Default", "Northwest", "Center", "By attribute", "Lock raster"); | ||
|
||
// set the default combo box value | ||
comboBox.setValue("Default"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can do these things independently from waiting for the RasterLayer
to load, and it might make sense to move them closer to line 152 (where we add the listener: comboBox.getSelectionModel().selectedItemProperty().addListener
)? That way it's clearer what these added values are going to be used for
// add draw status listener to the map view | ||
mapView.addDrawStatusChangedListener (drawStatusChangedEvent -> { | ||
// show progress indicator while map view is drawing | ||
if (drawStatusChangedEvent.getDrawStatus() == DrawStatus.IN_PROGRESS) { | ||
progressIndicator.setVisible(true); | ||
} | ||
else { | ||
progressIndicator.setVisible(false); | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can simplify this a fair bit by passing the result of the comparison ==
straight into .setVisible
.
Up to you and @Rachael-E to decide if this is a sacrifice of legibility though
Other than that, I think the inside comment does explain the whole block, so we could get rid of // add draw status lisener...
// add draw status listener to the map view | |
mapView.addDrawStatusChangedListener (drawStatusChangedEvent -> { | |
// show progress indicator while map view is drawing | |
if (drawStatusChangedEvent.getDrawStatus() == DrawStatus.IN_PROGRESS) { | |
progressIndicator.setVisible(true); | |
} | |
else { | |
progressIndicator.setVisible(false); | |
} | |
}); | |
// show progress indicator while map view is drawing | |
mapView.addDrawStatusChangedListener(drawStatusChangedEvent -> | |
progressIndicator.setVisible(drawStatusChangedEvent.getDrawStatus() == DrawStatus.IN_PROGRESS) | |
); |
// add raster layer as an operational layer to the map | ||
map.getOperationalLayers().add(rasterLayer); | ||
|
||
// listen for the raster layer to finish loading |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think wait
is a bit more plain english than the technical term listen
// listen for the raster layer to finish loading | |
// wait for the raster layer to finish loading |
ImageServiceRaster imageServiceRaster = new ImageServiceRaster(imageServiceURL); | ||
rasterLayer = new RasterLayer(imageServiceRaster); | ||
|
||
// add raster layer as an operational layer to the map |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add an a
to make it more plain english?
// add raster layer as an operational layer to the map | |
// add a raster layer as an operational layer to the map |
// listen for the raster layer to finish loading | ||
rasterLayer.addDoneLoadingListener(() -> { | ||
if (rasterLayer.getLoadStatus() == LoadStatus.LOADED) { | ||
// when loaded, set map view's viewpoint to the image service raster's center |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more possibility for plain english here as well?
// when loaded, set map view's viewpoint to the image service raster's center | |
// when loaded, set the map view's viewpoint to the image service raster's center |
.../main/java/com/esri/samples/apply_mosaic_rule_to_rasters/ApplyMosaicRuleToRastersSample.java
Show resolved
Hide resolved
@JonLavi I've created a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @sclaridge . Approving so that you can move on to the second review.
Just a few ideas for you.
One thing I noticed is that the progress spinner appears even when right-clicking, which can be a bit misleading as right-click doesn't do anything in this sample. It also appears when panning, which is technically correct (the MapView
is in 'drawing' state), but also not really representative for what's going on.
One way to get around that would be to add the listener when making the selection in the combobox, and remove it again once the drawing is finished. If this complicates the code too much though, perhaps it would be better to leave as is.
// create a combo box | ||
mosaicRuleComboBox = new ComboBox<>(); | ||
mosaicRuleComboBox.setMaxWidth(Double.MAX_VALUE); | ||
|
||
// add the mosaic rules to the combo box | ||
mosaicRuleComboBox.getItems().addAll("Default", "Northwest", "Center", "By attribute", "Lock raster"); | ||
|
||
// set the default combo box value | ||
mosaicRuleComboBox.getSelectionModel().select(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you wanted, you could instantiate the combobox directly with the items, instead of adding them in a separate line,
// create a combo box | |
mosaicRuleComboBox = new ComboBox<>(); | |
mosaicRuleComboBox.setMaxWidth(Double.MAX_VALUE); | |
// add the mosaic rules to the combo box | |
mosaicRuleComboBox.getItems().addAll("Default", "Northwest", "Center", "By attribute", "Lock raster"); | |
// set the default combo box value | |
mosaicRuleComboBox.getSelectionModel().select(0); | |
// create a combo box with the mosaic rules | |
mosaicRuleComboBox = new ComboBox<>( | |
FXCollections.observableArrayList("Default", "Northwest", "Center", "By attribute", "Lock raster")); | |
mosaicRuleComboBox.setMaxWidth(Double.MAX_VALUE); | |
// set the default combo box value | |
mosaicRuleComboBox.getSelectionModel().select(0); | |
@@ -0,0 +1,214 @@ | |||
/* | |||
* Copyright 2020 Esri. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2021 by now? 😁
private ComboBox<String> mosaicRuleComboBox; | ||
private MapView mapView; | ||
private MosaicRule mosaicRule; | ||
private RasterLayer rasterLayer; // keep loadable in scope to avoid garbage collection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there's any risk of RasterLayer going out of scope (it's inside the Map), but I might be wrong and misremembering the reason for this fix. Might be worth looking up again?
mapView.setMap(map); | ||
|
||
// create a raster layer from the image service raster | ||
ImageServiceRaster imageServiceRaster = new ImageServiceRaster("https://sampleserver7.arcgisonline.com/server/rest/services/amberg_germany/ImageServer"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we stick to the character limit? I think shortening it like this would be enough
ImageServiceRaster imageServiceRaster = new ImageServiceRaster("https://sampleserver7.arcgisonline.com/server/rest/services/amberg_germany/ImageServer"); | |
ImageServiceRaster imageServiceRaster = new ImageServiceRaster( | |
"https://sampleserver7.arcgisonline.com/server/rest/services/amberg_germany/ImageServer"); |
setupUI(); | ||
|
||
// create a progress indicator | ||
ProgressIndicator progressIndicator = new ProgressIndicator(ProgressIndicator.INDETERMINATE_PROGRESS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving out the type also works here.
Considering it's UI I'd be tempted to shove it in setupUI
as well, but it would require making it a class member, so that decision is up to you!
ProgressIndicator progressIndicator = new ProgressIndicator(ProgressIndicator.INDETERMINATE_PROGRESS); | |
ProgressIndicator progressIndicator = new ProgressIndicator(); |
// add the map view, control panel and progress indicator to the stack pane | ||
stackPane.getChildren().addAll(mapView,controlsVBox, progressIndicator); | ||
StackPane.setAlignment(controlsVBox, Pos.TOP_LEFT); | ||
StackPane.setMargin(controlsVBox, new Insets(10, 0, 0, 10)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps we can put some of this in setupUI
as well?
It's good to show that the MapView
belongs in the StackPane
though.
It would be quite a big pattern change, so maybe worth a discussion with the team, however it'd make away with a lot of JavaFX code and leave the Runtime code front an centre, so just an idea.
}); | ||
|
||
// add the map view, control panel and progress indicator to the stack pane | ||
stackPane.getChildren().addAll(mapView,controlsVBox, progressIndicator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing a space here:
stackPane.getChildren().addAll(mapView,controlsVBox, progressIndicator); | |
stackPane.getChildren().addAll(mapView, controlsVBox, progressIndicator); |
@Rachael-E I've moved the JavaFX set up and progress indicator into a separate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @sclaridge neat small sample! just a few minor comments and reordering of code to consider, as well as an update to the readme thanks to the new checker!
// sets the API key from the gradle.properties file as a Java system property | ||
systemProperty 'apiKey', apiKey |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should look into this more: if Jon is coming across this as a first time using this task others will too. I can take a look on a fresh windows setup!
@@ -0,0 +1,214 @@ | |||
/* | |||
* Copyright 2021 Esri. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this would have been ok to leave as 2020 since that's when the code was originally authored: no harm to update it to 2021 but just a note for future!
|
||
## Tags | ||
|
||
image service, mosaic rule, mosaic method, raster |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the checker is picking up that these aren't sorted alphabetically, gosh I wouldn't have noticed this at all otherwise!
image service, mosaic rule, mosaic method, raster | |
image service, mosaic method, mosaic rule, raster |
@@ -0,0 +1,43 @@ | |||
# Apply mosaic rule to rasters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Jon here, though checking the design I now understand why it's plural:
Mosaic rules are applied to mosaic datasets, which are a mesh of several rasters managed together as one
// setup the UI | ||
setupUI(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's move this to after the mapview has been set to the map: keeps consistency with our other samples where we open the code with our own Runtime specific set up.
} | ||
} else { | ||
// show alert if raster layer fails to load. | ||
new Alert(Alert.AlertType.ERROR, "Error loading raster layer.").show(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeh we could add that in here since this dialog box would pop up: if there is a meaningful message. Sometimes there isn't in which case we don't put that extra detail in.
case "Lock raster": | ||
mosaicRule.setMosaicMethod(MosaicMethod.LOCK_RASTER); | ||
mosaicRule.getLockRasterIds().clear(); | ||
mosaicRule.getLockRasterIds().addAll(Arrays.asList(1L, 7L, 12L)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too sure as a user why I have to add these lock raster IDs: can you add a comment to explain what this is? Is this selecting certain rasters from the mosaic dataset to display?
// create a progress indicator | ||
progressIndicator = new ProgressIndicator(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd move the progressIndicator out of here and put it in place where it is first called in the start method. You could then also remove it as a member variable.
// show progress indicator while map view is drawing | ||
mapView.addDrawStatusChangedListener(drawStatusChangedEvent -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// show progress indicator while map view is drawing | |
mapView.addDrawStatusChangedListener(drawStatusChangedEvent -> | |
// show progress indicator while map view is drawing | |
var progressIndicator = new ProgressIndicator(); | |
mapView.addDrawStatusChangedListener(drawStatusChangedEvent -> |
@Rachael-E I've added back the original feature service URL and rearranged some of the UI code. |
This sample was previously waiting for two issues to be fixed for the
LOCK_RASTER
method. I've set the target branch to dev so that the lock raster method will work correctly when the sample is publicly released.Currently, the
mapView
is instantiated and theDrawStatusChangedListener
set before the map is created so thatCOMPLETED
draw status events will be generated and the progress indicator can be used, as advised by the Java team.@jenmerritt I have added the new SS7 URL for the image raster service.
Thanks!
@JonLavi